<?php
namespace app\shop\library\pay;

use cubox\Cubox;
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Util\PemUtil;

class WeChat extends Pay{ 
    private $instance;
    private $config;
    public function __construct()
    {
        $config = Cubox::config('pay.wechat');
        

        // 'file:///path/to/merchant/apiclient_key.pem'
        $merchantPrivateKeyFilePath =  $config->apiclient_key;
        $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);


        if ($config->certsType == 'public'){
            // 'file:///path/to/wechatpay/publickey.pem'
            $platformPublicKeyFilePath = $config->public_key;
            $certsID = $config->public_key_id;
        }

        if ($config->certsType == 'cert'){

            // 'file:///path/to/wechatpay/cert.pem'
            $platformPublicKeyFilePath = $config->cert;
             // 从「微信支付平台证书」中获取「证书序列号」
            $certsID = PemUtil::parseCertificateSerialNo($platformPublicKeyFilePath);
        }
        
        
        $PlatformPublicKeyInstance = Rsa::from($platformPublicKeyFilePath, Rsa::KEY_TYPE_PUBLIC);

        $this->instance = Builder::factory([
            'mchid' => $config->merchantId,
            'serial' => $config->merchantCertificateSerial,
            'privateKey' => $merchantPrivateKeyInstance,
            'certs' => [
                $certsID => $PlatformPublicKeyInstance,
            ],
        ]);

        $this->config = $config;
    }

    public function create($order_id,$price,$title){

        $order = [
            'out_trade_no' => $order_id,
            'description' => $title,
            'notify_url' => $this->notify_url(),
            'amount' => [
                'total' => $price,
            ],
        ];

        $response = $this->instance->transactions->create('JSAPI', $order);

        if (!isset($response['prepay_id'])){
            Cubox::log('微信支付失败 '.json_encode($response));
            throw new \Exception('微信支付失败');
        }else{
            $prepayId = $response['prepay_id'];

            $prepay = [
                'appId' => $this->config->appId,
                'timeStamp' => (string)time(),
                'nonceStr' => uniqid(),
                'package' => 'prepay_id=' . $prepayId,
                'signType' => 'RSA',
            ];

            $prepay['paySign'] = $this->instance->sign->sign($prepay);

            return $prepay;
        }
    }

    public function close($order_id){
        $response = $this->instance->transactions->close($order_id);
        if ($response['trade_state'] == 'CLOSED'){
            return true;
        }else{
            Cubox::log('微信关闭订单失败 '.json_encode($response));
            return false;
        }
    }

    

}